#ifndef TSW_TIMER_H
#define TSW_TIMER_H

#include "mytype.h"
#include "lib_surport.h"

#ifdef __cplusplus
extern "C"
{
#endif

	struct swtm_cb_str
	{
		uint32_t period;
		uint32_t tick_cnt;
		uint8_t mode;
		uint8_t run_st;
		uint8_t pulse;
		uint8_t wave;
		void (*task)(void);
		struct swtm_cb_str *next;
	};

	typedef struct swtm_cb_str swtm_cb_type;

	struct swtm_manage_str
	{
		uint16_t tick_old;
		swtm_cb_type *list;
	};

	typedef struct swtm_manage_str swtm_manage_type;

	void swtm_init(swtm_manage_type *vect, uint16_t tick);
	void swtm_add(swtm_manage_type *vect, swtm_cb_type *tm_cb, void (*task)(void)); 
	void swtm_del(swtm_manage_type *vect, swtm_cb_type *tm_cb);						
	void swtm_reset(swtm_cb_type *tm_cb);											
	void swtm_start(swtm_cb_type *tm_cb);											
	void swtm_stop(swtm_cb_type *tm_cb);											
	void swtm_set(swtm_cb_type *tm_cb, uint8_t mode, uint32_t cmp);					
	void swtm_run(swtm_manage_type *vect, uint16_t tick);							

	typedef struct
	{
		int32_t sec_set;	 
		int32_t sec_cnt;	 
		int8_t rtc_sec_old;	 
		int8_t reset_at_end; 
		int8_t out_time_end; 
	} time_run_handle_type;

	typedef struct
	{
		uint32_t set;		  
		uint32_t cnt;		  
		uint8_t on;			  
		uint8_t limit_en;	  
		uint8_t reset_at_end; 
		uint8_t out_time_end; 
	} time_pulse_run_handle_type;

	void time_pulse_run_handle(time_pulse_run_handle_type *obj, uint8_t pulse); 
	void time_pulse_run_reset(time_pulse_run_handle_type *obj);

	void time_pulse_nev_run_handle(time_pulse_run_handle_type *obj, uint8_t pulse); 
	void time_pulse_nev_run_reset(time_pulse_run_handle_type *obj);

	typedef struct
	{
		uint16_t set;		  
		uint16_t div;		  
		uint16_t cnt;		  
		uint16_t div_cnt;	  
		uint8_t on;			  
		uint8_t limit_en;	  
		uint8_t reset_at_end; 
		uint8_t out_time_end; 
	} time_div_handle_type;

	void time_div_handle(time_div_handle_type *obj, uint8_t pulse); 
	void time_div_reset(time_div_handle_type *obj);

	void time_nev_div_handle(time_div_handle_type *obj, uint8_t pulse); 
	void time_nev_div_reset(time_div_handle_type *obj);

	typedef struct
	{
		uu8 en;
		uu8 st;
		uu16 cnt;
		uu16 otsv;
		void (*callback)(void);
	} swdg_type;

	void swdg_open(swdg_type *obj, uu16 ot, void (*back)(void));
	void swdg_close(swdg_type *obj);
	void swdg_feed(swdg_type *obj);
	void swdg_run(swdg_type *obj);

	typedef struct
	{
		uu16 base;
		uu16 cnt;
	} tm_tick16_type;

	typedef struct
	{
		uu32 base;
		uu32 cnt;
	} tm_tick32_type;

#define tm_tick16_run(tks) tks.cnt = lib_tick16_cnt - tks.base
#define tm_tick16_rst(tks) tks.base = lib_tick16_cnt
#define tm_tick32_run(tks) tks.cnt = lib_tick32_cnt - tks.base
#define tm_tick32_rst(tks) tks.base = lib_tick32_cnt

#define tm_tick_run(tks)        \
	do                          \
	{                           \
		if (sizeof(tks) == 4)   \
		{                       \
			tm_tick16_run(tks); \
		}                       \
		else                    \
		{                       \
			tm_tick32_run(tks); \
		}                       \
	} while (0)

#define tm_tick_rst(tks)        \
	do                          \
	{                           \
		if (sizeof(tks) == 4)   \
		{                       \
			tm_tick16_rst(tks); \
		}                       \
		else                    \
		{                       \
			tm_tick32_rst(tks); \
		}                       \
	} while (0)

	typedef struct
	{
		uu16 cnt;	  
		uu16 set;	  
		uu16 div_cnt; 
		uu16 div_set; 
	} div_time_type;

#define div_time_run(obj)               \
	do                                  \
	{                                   \
		obj.div_cnt++;                  \
		if (obj.div_cnt >= obj.div_set) \
		{                               \
			obj.div_cnt = 0;            \
			obj.cnt++;                  \
		}                               \
	} while (0)

#define div_time_rst(obj) \
	do                    \
	{                     \
		obj.cnt = 0;      \
		obj->div_cnt = 0; \
	} while (0)

#define div_time_set(obj, msv, divsv) \
	do                                \
	{                                 \
		obj.set = msv;                \
		obj.div_set = divsv;          \
	} while (0)

#define div_time_get(obj) ((uu32)(obj.cnt * obj.div_set) + obj->div_cnt)

	typedef struct
	{
		uu16 cnt;		 
		uu16 set;		 
		uu32 tick_start; 
		uu32 div_set;	 
	} div_tick_cnt_type;

#define div_tick_set(obj, msv, divsv) \
	do                                \
	{                                 \
		obj.set = msv;                \
		obj.div_set = divsv;          \
	} while (0)

#define div_tick_rst(obj)                 \
	do                                    \
	{                                     \
		obj.cnt = 0;                      \
		obj->tick_start = lib_tick32_cnt; \
	} while (0)

#define div_tick_run(obj)                                           \
	do                                                              \
	{                                                               \
		if ((uu32)(lib_tick32_cnt - obj.tick_start) >= obj.div_set) \
		{                                                           \
			obj.tick_start += obj.div_set;                          \
			obj.cnt++;                                              \
		}                                                           \
	} while (0)

#ifdef __cplusplus
}
#endif

#endif 
